const { Controller } = require('egg');

class GroupController extends Controller {
  // 创建群聊
  async create() {
    const { ctx, app, service } = this;
    // 1. 参数验证
    ctx.validate({
      ids: {
        type: 'array',
        required: true,
        desc: '群成员id列表'
      }
    });
    const { ids } = ctx.request.body;
    const id = ctx.authUser.id;
    // 2. 验证这些成员是否为我的好友
    const friend = await app.model.Friend.findAll({
      where: {
        user_id: id,
        friend_id: ids
      },
      include: [
        {
          model: app.model.User,
          as: 'friendInfo',
          attributes: ['nickname', 'username']
        }
      ]
    });
    if (!friend) {
      ctx.throw(400, '请选择好友创建群聊');
    }
    if (friend.length !== ids.length) {
      ctx.throw(400, '处理错误，请重新选择好友创建群聊');
    }
    // 3. 创建群聊
    let groupName = friend.map((item) => item.nickname);
    groupName.unshift(ctx.authUser.nickname || ctx.authUser.username);
    groupName = groupName.join(',').substring(0, 15);
    // 3.1 创建群聊
    const group = await app.model.Group.create({
      name: groupName,
      avatar: '',
      user_id: id
    });
    // 4. 添加群成员
    const data = friend.map((item) => {
      return {
        user_id: item.friend_id,
        group_id: group.id,
        nickname: item.nickname
      };
    });
    data.unshift({
      user_id: id,
      group_id: group.id,
      nickname: ctx.authUser.nickname || ctx.authUser.username
    });
    const groupMember = await app.model.GroupUser.bulkCreate(data);
    // 5. 消息推送
    let message = {
      id: new Date().getTime(), // 唯一id，后端生成唯一id
      from_avatar: ctx.authUser.avatar, // 发送者头像
      from_name: ctx.authUser.nickname || ctx.authUser.username, // 发送者昵称
      from_id: id, // 发送者id
      to_id: group.id, // 接收人/群 id
      to_name: group.name, // 接收人/群 名称
      to_avatar: group.avatar, // 接收人/群 头像
      chat_type: 'group', // 接收类型
      type: 'system', // 消息类型
      data: '创建群聊成功，可以开始聊天啦', // 消息内容
      options: {}, // 其他参数
      create_time: new Date().getTime(), // 创建时间
      isremove: 0, // 是否撤回
      group: group
    };
    data.forEach((item) => {
      ctx.sendMessage(item.user_id, message);
    });
    // 6. 返回结果
    ctx.success(message);
  }
  // 获取群聊列表
  async getGroupList() {
    const { ctx, app } = this;
    const id = ctx.authUser.id;
    // 1. 参数验证 和格式整理
    ctx.validate({
      page: { type: 'int', required: false, desc: '页码' }
    });
    let { page } = ctx.params;
    page = page < 1 ? 1 : page;
    const limit = 10;
    const offset = (page - 1) * limit;
    // 2. 查询用户是否存在
    const user = await app.model.User.findOne({
      where: {
        id: id,
        status: 1
      }
    });
    if (!user) {
      ctx.throw(400, '用户不存在或被管理员封禁');
    }
    // 3. 获取群聊列表
    const groupList = await app.model.Group.findAll({
      where: {
        user_id: id
      },
      offset,
      limit
    });
    // 4. 返回结果
    ctx.success(groupList);
  }
  // 获得群聊详情信息
  async getGroupInfo() {
    const { ctx, app } = this;
    const id = ctx.authUser.id;
    // 1. 参数验证 和格式整理
    ctx.validate({
      group_id: { type: 'int', required: true, desc: '群聊id' }
    });
    const { group_id } = ctx.params;
    // 2. 查看群成员是否存在
    let group = await app.model.Group.findOne({
      where: {
        id: group_id,
        status: 1
      },
      include: [
        {
          model: app.model.GroupUser,
          attributes: ['user_id', 'nickname'],
          include: [
            {
              model: app.model.User,
              attributes: ['id', 'nickname', 'avatar', 'username']
            }
          ]
        }
      ]
    });

    if (!group) {
      ctx.throw(400, '群聊不存在或被管理员封禁');
    }
    // 3. 判断本人是否为群成员
    const groupUser = group.group_users.find((item) => item.user_id === id);
    if (!groupUser) {
      ctx.throw(400, '您不是该群成员');
    }
    // 判断本人是否为群主
    group = JSON.parse(JSON.stringify(group));
    if (group.user_id === id) {
      group.is_admin = true;
    }
    ctx.success(group);
  }
  // 修改群昵称
  async updateGroupname() {
    const { ctx, app } = this;
    const id = ctx.authUser.id;
    // 1. 参数验证 和格式整理
    console.log('---------------');
    ctx.validate({
      group_id: { type: 'int', required: true, desc: '群聊id' },
      name: { type: 'string', required: true, desc: '群昵称' }
    });
    const { group_id } = ctx.params;
    const { name } = ctx.request.body;
    // 2. 查看群是否存在
    const group = await app.model.Group.findOne({
      where: {
        id: group_id,
        status: 1
      },
      include: [
        {
          model: app.model.GroupUser,
          attributes: ['user_id', 'nickname']
        }
      ]
    });
    if (!group) {
      ctx.throw(400, '群聊不存在或被管理员封禁');
    }
    group.name = name;
    await group.save();
    // 3. 推送给所有群成员
    const fromName = ctx.authUser.nickname || ctx.authUser.username;
    let message = {
      id: new Date().getTime(), // 唯一id，后端生成唯一id
      from_avatar: ctx.authUser.avatar, // 发送者头像
      from_name: fromName, // 发送者昵称
      from_id: id, // 发送者id
      to_id: group.id, // 接收人/群 id
      to_name: group.name, // 接收人/群 名称
      to_avatar: group.avatar, // 接收人/群 头像
      chat_type: 'group', // 接收类型
      type: 'system', // 消息类型
      data: `${fromName}修改群昵称为${name}`, // 消息内容
      options: {}, // 其他参数
      create_time: new Date().getTime(), // 创建时间
      isremove: 0, // 是否撤回
      group: group
    };
    group.group_users.forEach((item) => {
      ctx.sendMessage(item.user_id, message);
    });
    // 4. 返回结果
    ctx.success(group);
  }
  // 修改群公告
  async updateGroupRemark() {
    const { ctx, app } = this;
    const id = ctx.authUser.id;
    // 1. 参数验证 和格式整理
    ctx.validate({
      group_id: { type: 'int', required: true, desc: '群聊id' },
      remark: { type: 'string', required: true, desc: '群公告' }
    });
    const { group_id } = ctx.params;
    const { remark } = ctx.request.body;
    // 2. 查看群是否存在
    const group = await app.model.Group.findOne({
      where: {
        id: group_id,
        status: 1
      },
      include: [
        {
          model: app.model.GroupUser,
          attributes: ['user_id', 'nickname']
        }
      ]
    });
    if (!group) {
      ctx.throw(400, '群聊不存在或被管理员封禁');
    }
    group.remark = remark;
    await group.save();
    // 3. 推送给所有群成员
    const fromName = ctx.authUser.nickname || ctx.authUser.username;
    let message = {
      id: new Date().getTime(), // 唯一id，后端生成唯一id
      from_avatar: ctx.authUser.avatar, // 发送者头像
      from_name: fromName, // 发送者昵称
      from_id: id, // 发送者id
      to_id: group.id, // 接收人/群 id
      to_name: group.name, // 接收人/群 名称
      to_avatar: group.avatar, // 接收人/群 头像
      chat_type: 'group', // 接收类型
      type: 'system', // 消息类型
      data: `${fromName}修改群公告为${remark}`, // 消息内容
      options: {}, // 其他参数
      create_time: new Date().getTime(), // 创建时间
      isremove: 0, // 是否撤回
      group: group
    };
    group.group_users.forEach((item) => {
      ctx.sendMessage(item.user_id, message);
    });
    // 4. 返回结果
    ctx.success(group);
  }
  // 修改用户在群中的昵称
  async updateGroupNickname() {
    const { ctx, app } = this;
    const id = ctx.authUser.id;
    // 1. 参数验证 和格式整理
    ctx.validate({
      group_id: { type: 'int', required: true, desc: '群聊id' },
      nickname: { type: 'string', required: true, desc: '群昵称' }
    });
    const { group_id } = ctx.params;
    const { nickname } = ctx.request.body;
    // 2. 查看群是否存在
    const group = await app.model.Group.findOne({
      where: {
        id: group_id,
        status: 1
      },
      include: [
        {
          model: app.model.GroupUser,
          attributes: ['user_id', 'nickname']
        }
      ]
    });
    if (!group) {
      ctx.throw(400, '群聊不存在或被管理员封禁');
    }
    // 3. 查看我是否为本群用户
    const groupUser = await app.model.GroupUser.findOne({
      where: {
        user_id: id,
        group_id: group_id
      }
    });
    if (!groupUser) {
      ctx.throw(400, '您不是本群成员');
    }
    // 4. 修改群昵称
    let oldNickname = groupUser.nickname;
    groupUser.nickname = nickname;
    await groupUser.save();
    // 5. 推送给所有群成员
    const fromName = ctx.authUser.nickname || ctx.authUser.username;
    let message = {
      id: new Date().getTime(), // 唯一id，后端生成唯一id
      from_avatar: ctx.authUser.avatar, // 发送者头像
      from_name: fromName, // 发送者昵称
      from_id: id, // 发送者id
      to_id: group.id, // 接收人/群 id
      to_name: group.name, // 接收人/群 名称
      to_avatar: group.avatar, // 接收人/群 头像
      chat_type: 'group', // 接收类型
      type: 'system', // 消息类型
      data: `${oldNickname}修改了昵称为${nickname}`, // 消息内容
      options: {}, // 其他参数
      create_time: new Date().getTime(), // 创建时间
      isremove: 0, // 是否撤回
      group: group
    };
    group.group_users.forEach((item) => {
      ctx.sendMessage(item.user_id, message);
    });
    // 6. 返回结果
    ctx.success(group);
  }
  // 邀请某人进去群聊
  async invite() {
    const { ctx, app } = this;
    const id = ctx.authUser.id;
    // 参数验证 和格式整理
    ctx.validate({
      user_id: { type: 'int', required: true, desc: '被邀请用户id' },
      group_id: { type: 'int', required: true, desc: '群聊id' },
      nickname: { type: 'string', required: true, desc: '用户名称' }
    });
    const { user_id, group_id, nickname } = ctx.request.body;
    // 查看群是否存在
    const group = await app.model.Group.findOne({
      where: {
        id: group_id,
        status: 1
      },
      include: [
        {
          model: app.model.GroupUser,
          attributes: ['user_id', 'nickname']
        }
      ]
    });
    if (!group) {
      ctx.throw(400, '群聊不存在或被管理员封禁');
    }
    //查看发出邀请的用户是否存在
    const user = await app.model.User.findOne({
      where: {
        id: id,
        status: 1
      },
      include: []
    });
    if (!user) {
      ctx.throw(400, '用户不存在或被管理员封禁');
    }
    // 查看发出邀请的用户是否在群聊中
    const groupUser = await app.model.GroupUser.findOne({
      where: {
        user_id: id,
        group_id: group_id
      }
    });
    if (!groupUser) {
      ctx.throw(400, '您不是本群成员');
    }
    // 查看被邀请用户是否存在
    const iUser = await app.model.User.findOne({
      where: {
        id: user_id,
        status: 1
      }
    });
    if (!iUser) {
      ctx.throw(400, '被邀请用户不存在或被管理员封禁');
    }
    // 查看用户是否已经在群聊中
    const groupIUser = await app.model.GroupUser.findOne({
      where: {
        user_id: user_id,
        group_id: group_id
      }
    });
    if (groupIUser) {
      ctx.throw(400, '用户已经在群聊中');
    }
    // 添加用户到群聊
    const addUser = await app.model.GroupUser.create({
      user_id,
      group_id,
      nickname
    });
    // 将消息推送给群中的所有人
    const fromName = ctx.authUser.nickname || ctx.authUser.username;
    const toName = iUser.nickname || iUser.username;
    let message = {
      id: new Date().getTime(), // 唯一id，后端生成唯一id
      from_avatar: ctx.authUser.avatar, // 发送者头像
      from_name: fromName, // 发送者昵称
      from_id: id, // 发送者id
      to_id: group.id, // 接收人/群 id
      to_name: group.name, // 接收人/群 名称
      to_avatar: group.avatar, // 接收人/群 头像
      chat_type: 'group', // 接收类型
      type: 'system', // 消息类型
      data: `${fromName}邀请${toName}加入群聊`, // 消息内容
      options: {}, // 其他参数
      create_time: new Date().getTime(), // 创建时间
      isremove: 0, // 是否撤回
      group: group
    };
    group.group_users.forEach((item) => {
      ctx.sendMessage(item.user_id, message);
    });
    // // 将消息推送给被邀请的用户
    ctx.sendMessage(user_id, message);
    // 返回消息
    if (addUser) {
      return ctx.success('添加成功');
    }
    ctx.success('添加失败');
  }

  // 将某人踢出群聊
  async removeGroupUser() {
    const { ctx, app } = this;
    const id = ctx.authUser.id;
    // 参数验证
    ctx.validate({
      user_id: { type: 'int', required: true, desc: '被邀请用户id' },
      group_id: { type: 'int', required: true, desc: '群聊id' },
      nickname: { type: 'string', required: true, desc: '用户名称' }
    });
    const { user_id, group_id, nickname } = ctx.request.body;
    // 查看群是否存在
    const group = await app.model.Group.findOne({
      where: {
        id: group_id,
        status: 1
      },
      include: [
        {
          model: app.model.GroupUser,
          attributes: ['user_id', 'nickname']
        }
      ]
    });
    if (!group) {
      ctx.throw(400, '群聊不存在或被管理员封禁');
    }
    // 检查是否是管理员操作
    if (group.user_id !== id) {
      ctx.throw(400, '只有群主才能操作哦');
    }
    // 检查用户是否在群聊中
    const iUser = group.group_users.find((item) => item.user_id === user_id);
    if (!iUser) {
      ctx.throw(400, '用户不在群聊中');
    }
    // 不能踢出自己
    if (iUser.user_id === id) {
      ctx.throw(400, '不能踢出自己哦');
    }
    // 剔出操作
    const result = await app.model.GroupUser.destroy({
      where: { user_id, group_id }
    });
    // 发送系统消息
    const fromName = ctx.authUser.nickname || ctx.authUser.username;
    const toName = iUser.nickname || iUser.username;
    let message = {
      id: new Date().getTime(), // 唯一id，后端生成唯一id
      from_avatar: ctx.authUser.avatar, // 发送者头像
      from_name: fromName, // 发送者昵称
      from_id: id, // 发送者id
      to_id: group.id, // 接收人/群 id
      to_name: group.name, // 接收人/群 名称
      to_avatar: group.avatar, // 接收人/群 头像
      chat_type: 'group', // 接收类型
      type: 'system', // 消息类型
      data: `${fromName}将${toName}移除群聊`, // 消息内容
      options: {}, // 其他参数
      create_time: new Date().getTime(), // 创建时间
      isremove: 0, // 是否撤回
      group: group
    };
    group.group_users.forEach((item) => {
      ctx.sendMessage(item.user_id, message);
    });
    // // 将消息推送给被踢出用户
    ctx.sendMessage(user_id, message);
    if (result) {
      return ctx.success('踢出成功');
    }
    ctx.throw(400, '踢出失败');
  }
  // 退出群聊
  async quitGroup() {
    const { ctx, app } = this;
    const id = ctx.authUser.id;
    // 1. 参数验证 和格式整理
    ctx.validate({
      group_id: { type: 'int', required: true, desc: '群聊id' }
    });
    const { group_id } = ctx.params;
    // 2. 查看群是否存在
    const group = await app.model.Group.findOne({
      where: {
        id: group_id,
        status: 1
      },
      include: [
        {
          model: app.model.GroupUser,
          attributes: ['user_id', 'nickname']
        }
      ]
    });
    // 3. 区分是群主还是群成员  群主就解散群聊  群成员就退出群聊
    if (group.user_id === id) {
      // 群主解散群聊
      await app.model.Group.destroy({
        where: {
          id: group_id
        }
      });
      // 推送给所有群成员
      const fromName = ctx.authUser.nickname || ctx.authUser.username;
      let message = {
        id: new Date().getTime(), // 唯一id，后端生成唯一id
        from_avatar: ctx.authUser.avatar, // 发送者头像
        from_name: fromName, // 发送者昵称
        from_id: id, // 发送者id
        to_id: group.id, // 接收人/群 id
        to_name: group.name, // 接收人/群 名称
        to_avatar: group.avatar, // 接收人/群 头像
        chat_type: 'group', // 接收类型
        type: 'system', // 消息类型
        data: `${fromName}解散了此群聊`, // 消息内容
        options: {}, // 其他参数
        create_time: new Date().getTime(), // 创建时间
        isremove: 0, // 是否撤回
        group: group
      };
      group.group_users.forEach((item) => {
        ctx.sendMessage(item.user_id, message);
      });
      // 4. 返回结果
      ctx.success(group);
    } else {
      // 群成员退出群聊
      await app.model.GroupUser.destroy({
        where: {
          user_id: id,
          group_id: group_id
        }
      });
      // 推送给所有群成员
      const fromName = ctx.authUser.nickname || ctx.authUser.username;
      let message = {
        id: new Date().getTime(), // 唯一id，后端生成唯一id
        from_avatar: ctx.authUser.avatar, // 发送者头像
        from_name: fromName, // 发送者昵称
        from_id: id, // 发送者id
        to_id: group.id, // 接收人/群 id
        to_name: group.name, // 接收人/群 名称
        to_avatar: group.avatar, // 接收人/群 头像
        chat_type: 'group', // 接收类型
        type: 'system', // 消息类型
        data: `${fromName}退出了此群聊`, // 消息内容
        options: {}, // 其他参数
        create_time: new Date().getTime(), // 创建时间
        isremove: 0, // 是否撤回
        group: group
      };
      group.group_users.forEach((item) => {
        ctx.sendMessage(item.user_id, message);
      });
      // 4. 返回结果
      ctx.success(group);
    }
  }
  // 根据群聊id获得群信息
  async getGroupByIdInfo() {
    const { ctx, app } = this;
    const { group_id } = ctx.params;
    // 1. 参数验证
    ctx.validate({
      group_id: { type: 'int', required: true, desc: '群聊id' }
    });
    // 2. 查看群是否存在
    const group = await app.model.Group.findOne({
      where: {
        id: group_id,
        status: 1
      },
      include: [
        {
          model: app.model.GroupUser,
          attributes: ['user_id', 'nickname']
        }
      ]
    });
    if (!group) {
      ctx.throw(400, '群聊不存在或被管理员封禁');
    }
    ctx.success(group);
  }
  // 生成群二维码
  async createGroupQRCode() {
    const { ctx, app } = this;
    const { group_id } = ctx.params;
    // 1. 参数验证
    ctx.validate({
      group_id: { type: 'int', required: true, desc: '群聊id' }
    });
    // 2. 查看群是否存在
    const group = await app.model.Group.findOne({
      where: {
        id: group_id,
        status: 1
      },
      include: [
        {
          model: app.model.GroupUser,
          attributes: ['user_id', 'nickname']
        }
      ]
    });
    if (!group) {
      ctx.throw(400, '群聊不存在或被管理员封禁');
    }
    ctx.generateQRCode(
      JSON.stringify({
        type: 'group',
        id: group.id,
        name: group.name,
        avatar: group.avatar,
        chat_type: 'group'
      })
    );
  }
  // 主动加入某个群聊
  async joinGroup() {
    const { ctx, app } = this;
    const id = ctx.authUser.id;
    // 1. 参数验证
    ctx.validate({
      group_id: {
        type: 'int',
        required: true,
        desc: '群聊id'
      }
    });
    const { group_id } = ctx.params;
    // 判断用户是否存在
    const user = await app.model.User.findOne({ where: { id: id, status: 1 } });
    if (!user) {
      ctx.throw(400, '用户不存在或被管理员封禁');
    }
    // 2. 查看群是否存在
    const group = await app.model.Group.findOne({
      where: {
        id: group_id,
        status: 1
      },
      include: [
        {
          model: app.model.GroupUser,
          attributes: ['user_id', 'nickname']
        }
      ]
    });
    if (!group) {
      ctx.throw(400, '群聊不存在或被管理员封禁');
    }
    // 3. 加入群聊
    if (group.group_users.find((item) => item.user_id == id)) {
      ctx.throw(400, '你已经在该群聊中');
    }
    const result = await app.model.GroupUser.create({
      user_id: id,
      group_id: group_id,
      nickname: user.nickname ? user.nickname : user.username
    });
    if (!result) {
      ctx.throw(400, '加入群聊失败');
    }
    // 通知群消息
    let message = {
      id: new Date().getTime(), // 唯一id，后端生成唯一id
      from_avatar: ctx.authUser.avatar, // 发送者头像
      from_name: user.nickname ? user.nickname : user.username, // 发送者昵称
      from_id: id, // 发送者id
      to_id: group.id, // 接收人/群 id
      to_name: group.name, // 接收人/群 名称
      to_avatar: group.avatar, // 接收人/群 头像
      chat_type: 'group', // 接收类型
      type: 'system', // 消息类型
      data: `${user.nickname ? user.nickname : user.username}加入群聊`, // 消息内容
      options: {}, // 其他参数
      create_time: new Date().getTime(), // 创建时间
      isremove: 0, // 是否撤回
      group: group
    };
    // 消息推送
    group.group_users.forEach((item) => {
      // 群中的人
      ctx.sendMessage(item.user_id, message);
    });
    ctx.success('加入群聊成功');
  }
}

module.exports = GroupController;
